package org.cybzacg.convert.exception;

import lombok.Getter;
import org.cybzacg.convert.enums.ConversionError;

import java.io.Serial;

/**
 * 转换异常抽象基类
 * 提供转换异常的通用实现
 *
 * @author cybzacg.blog
 * @version 3.0
 * @since 3.0
 */
@Getter
public abstract class AbstractConversionException extends RuntimeException implements IConversionException {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 错误类型
     */
    protected final ConversionError errorType;

    /**
     * 源类型
     */
    protected final Class<?> sourceType;

    /**
     * 目标类型
     */
    protected final Class<?> targetType;

    /**
     * 源值
     */
    protected final Object sourceValue;

    /**
     * 构造方法
     *
     * @param errorType 错误类型
     * @param message 异常消息
     * @param cause 原因异常
     * @param sourceType 源类型
     * @param targetType 目标类型
     * @param sourceValue 源值
     */
    protected AbstractConversionException(ConversionError errorType, String message, Throwable cause,
                                        Class<?> sourceType, Class<?> targetType, Object sourceValue) {
        super(message, cause);
        this.errorType = errorType != null ? errorType : ConversionError.UNKNOWN_ERROR;
        this.sourceType = sourceType;
        this.targetType = targetType;
        this.sourceValue = sourceValue;
    }

    /**
     * 构造方法
     *
     * @param errorType 错误类型
     * @param message 异常消息
     * @param sourceType 源类型
     * @param targetType 目标类型
     * @param sourceValue 源值
     */
    protected AbstractConversionException(ConversionError errorType, String message,
                                        Class<?> sourceType, Class<?> targetType, Object sourceValue) {
        this(errorType, message, null, sourceType, targetType, sourceValue);
    }


    @Override
    public String getDetailMessage() {
        StringBuilder sb = new StringBuilder();
        sb.append(getMessage());

        if (sourceType != null) {
            sb.append("\n源类型: ").append(sourceType.getName());
        }
        if (targetType != null) {
            sb.append("\n目标类型: ").append(targetType.getName());
        }
        if (sourceValue != null) {
            sb.append("\n源值: ").append(sourceValue);
            sb.append("\n源值类型: ").append(sourceValue.getClass().getName());
        }

        if (getCause() != null) {
            sb.append("\n原因: ").append(getCause().getMessage());
        }

        return sb.toString();
    }
}
